import Vue from 'vue';

import 'normalize.css/normalize.css'; // A modern alternative to CSS resets

import ElementUI from 'element-ui';
import { Message, MessageBox } from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import 'babel-polyfill'; // 兼容ie

import '@/styles/index.scss'; // global css

import App from './App';
import store from './store';
import router from './router';
import * as filters from './filters';

import '@/icons'; // icon
import '@/permission'; // permission control
import '@/global'; // 注册全局组件

/**
 * This project originally used easy-mock to simulate data,
 * but its official service is very unstable,
 * and you can build your own service if you need it.
 * So here I use Mock.js for local emulation,
 * it will intercept your request, so you won't see the request in the network.
 * If you remove `../mock` it will automatically request easy-mock data.
 */
import '../mock'; // simulation data 模拟数据时用，实际开发中可以去掉
Vue.config.productionTip = false; // 阻止 vue 在启动时生成生产提示(控制台中)

// 如果已在index.html用cdn引入时可注释掉
Vue.use(ElementUI);

// 引入echarts
import * as echarts from 'echarts';
Vue.prototype.$echarts = echarts;

// 注册全局的过滤器
for (const key of Object.keys(filters)) {
  Vue.filter(key, filters[key]);
}

// 统一的网络请求处理
Object.defineProperty(Vue.prototype, '$http', {
  value: function(requestPromise, successCallback, errorCallback, selfHandle) {
    requestPromise.then(res => {
      if (!res) return;
      // 针对res.ret === 0
      if (res.ret === 0) {
        successCallback && successCallback(res);
      } else {
        // 其他情况，当成错误信息显示
        throw new Error(res.message || '请求失败，请联系开发者！');
      }
    }).catch(err => {
      // 排除特殊情况
      if (!selfHandle) {
        // 显示错误信息
        Message({
          message: err.message,
          type: 'error',
          duration: 5 * 1000
        });
      }
      errorCallback && errorCallback(err);
    });
  }
});

/**
 * 全局确认框
 * @param {String} title 标题
 * @param {String} content 文本内容
 * @param {Function} confirmCallback 确定按钮的回调函数
 * @param {Function} cancelCallback 取消按钮回调函数
 */
Object.defineProperty(Vue.prototype, '$confirm', {
  value: function(title, content, confirmCallback, cancelCallback) {
    MessageBox.confirm(content, title, {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(() => {
      confirmCallback && confirmCallback();
    }).catch(() => {
      cancelCallback && cancelCallback();
    });
  }
});

// 全局图片路径处理
Object.defineProperty(Vue.prototype, '$getALiUrl', {
  value: function(src) {
    if (src) {
      if (/http/.test(src)) return src;
      return 'https://cube.elemecdn.com/' + src;
    }
  }
});

new Vue({
  el: '#app',
  router,
  data: {
    Bus: new Vue() // 用于兄弟组件通信
  },
  store,
  render: h => h(App)
});
